package client.updater;

import constans.ConfigurationConstans;
import constans.TimeConstans;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import utils.LogUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;


class Update {


    private String currentVersion;
    private Logger logger;



    public Update(String currentVersion, Logger logger){
        this.currentVersion = currentVersion;
        this.logger = logger;
    }



    public void run()
            throws HttpException, IOException{

            HttpClient client = new HttpClient();
            client.getHttpConnectionManager().getParams().setConnectionTimeout(3000); //Set timout connection - 3s

            GetMethod get = new GetMethod(ConfigurationConstans.RARC_UPDATE_URL + currentVersion);

            logger.log(Level.INFO,"Get: " + ConfigurationConstans.RARC_UPDATE_URL + currentVersion);

            try {

                int resultCode = client.executeMethod(get);

                if (resultCode == HttpStatus.SC_GONE) {

                    logger.log(Level.INFO,"This computer has old version of rArc...Get new version: " + ConfigurationConstans.RARC_SINSTALLER_URL+ConfigurationConstans.RARC_SINSTALLER_FILENAME);

                    get        = new GetMethod(ConfigurationConstans.RARC_SINSTALLER_URL+ConfigurationConstans.RARC_SINSTALLER_FILENAME);
                    resultCode = client.executeMethod(get);

                    if (resultCode == HttpStatus.SC_OK) {

                        saveFile(get.getResponseBodyAsStream());

                        get.releaseConnection();

                        logger.log(Level.INFO,"Launch rArcSInstaller");

                        Runtime.getRuntime().exec(ConfigurationConstans.RARC_SINSTALLER_FILENAME);
                    }
                } else {
                    logger.log(Level.INFO,"This computer has correct version of rArc");
                }
            } catch (HttpException e) {
                if (get != null) {
                    get.releaseConnection();
                }
                throw new HttpException(e.getMessage());
            } catch (IOException e) {
                if (get != null) {
                    get.releaseConnection();
                }
                throw new IOException(e.getMessage());
            }
    }


    private void saveFile(InputStream inStream)
            throws IOException {
        
        FileOutputStream fos = null;

        try {
            
            fos = new FileOutputStream(new File(ConfigurationConstans.RARC_SINSTALLER_FILENAME));

            byte[] buffer   = new byte[1024];
            int    numBytes = 0;

            while ((numBytes = inStream.read(buffer)) != -1)
                fos.write(buffer, 0, numBytes);
            fos.close();
            
        } catch (IOException e) {
            if (fos != null) {
                try {
                    fos.close();
                } catch (IOException ex) {}
            }
            throw new IOException(e);
        }
    }

}




public class Updater {

    private final static int factor      = 2;
    private final static int maxTries = 5;    
    private static int numberTries;
    private static long sleepTime;
    private static boolean success;

    
    //MAIN
    public static void main(String[] args) {

       Logger logger = null;

        try {

             logger = LogUtils.getLogger("rArcUpdate", "rArcUpdate.log");
             logger.log(Level.INFO,"Create log file");
            
             while (true) {

                try {

                String currentVersion = args[0];

                logger.log(Level.INFO,"Current version("+currentVersion+")");

                new Update(currentVersion,logger).run();
                success = true;     
                
                } catch (HttpException e) {
                    logger.log(Level.WARNING, e.getMessage());
                    success = false;
                } catch (IOException e) {
                    logger.log(Level.WARNING, e.getMessage());
                    success = false;
                }

                setTimeSleep();

                try {

                    logger.log(Level.INFO,"Sleep "+sleepTime/TimeConstans.MINUTE+" Minutes");
                    Thread.sleep(sleepTime);

                } catch (InterruptedException e) {
                    logger.log(Level.SEVERE, e.getMessage());
                    break;
                }
            }
        } catch (IOException e) {
            logger = null;
        }       
    }

    private static void setTimeSleep(){
        if (success) {
            sleepTime = TimeConstans.DAY;
        }
        else {
            if (numberTries < maxTries) {
                numberTries++;
                sleepTime = TimeConstans.MINUTE * (numberTries * factor);
            }
            else {
                    sleepTime   = TimeConstans.DAY;
                    numberTries = 0;
            }
        }
    }


    
}
